// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space 
// Source File Name:   LinePlotter3D.java

package com.java4less.rchart;

import com.java4less.rchart.gc.ChartColor;
import com.java4less.rchart.gc.ChartGraphics;
import com.java4less.rchart.gc.ChartImage;
import com.java4less.rchart.gc.Polygon;
import java.util.Vector;

// Referenced classes of package com.java4less.rchart:
//			Plotter, LineDataSerie, FillStyle, LineStyle, 
//			ChartLabel, DataSerie, Scale

public class LinePlotter3D extends Plotter
{

	public boolean fixedLimits;
	public LineStyle border;
	public int interLineSpace;

	public LinePlotter3D()
	{
		fixedLimits = false;
		border = null;
		interLineSpace = 0;
	}

	protected double[][] clipLines(double Points[][], double MaxY, double MinY)
	{
		int position = 0;
		int lastPointPosition = 0;
		double result[][] = new double[2][Points[0].length * 2];
		int resultCount = 0;
		if (Points[0].length == 0)
			return Points;
		if (Points[1][0] < MinY)
			lastPointPosition = 1;
		if (Points[1][0] > MaxY)
			lastPointPosition = 2;
		if (lastPointPosition == 0)
		{
			result[0][0] = Points[0][0];
			result[1][0] = Points[1][0];
			resultCount++;
		}
		for (int i = 1; i < Points[0].length; i++)
		{
			position = 0;
			if (Points[1][i] < MinY)
				position = 1;
			if (Points[1][i] > MaxY)
				position = 2;
			if (position == 0 && lastPointPosition == 0)
			{
				result[0][resultCount] = Points[0][i];
				result[1][resultCount] = Points[1][i];
				resultCount++;
			}
			if (position != lastPointPosition && (position == 0 || lastPointPosition == 0))
			{
				double limit = MinY;
				if (position == 2 || lastPointPosition == 2)
					limit = MaxY;
				double slope = (Points[0][i] - Points[0][i - 1]) / (Points[1][i] - Points[1][i - 1]);
				double newX = Points[0][i - 1] + slope * (limit - Points[1][i - 1]);
				double newX1 = Points[0][i];
				if (position == 0 && newX1 < newX)
				{
					result[0][resultCount] = newX1;
					result[1][resultCount] = Points[1][i];
					resultCount++;
				}
				result[0][resultCount] = newX;
				result[1][resultCount] = limit;
				resultCount++;
				if (position == 0 && newX1 >= newX)
				{
					result[0][resultCount] = newX1;
					result[1][resultCount] = Points[1][i];
					resultCount++;
				}
			}
			if (position != lastPointPosition && position != 0 && lastPointPosition != 0)
			{
				double slope = (Points[0][i] - Points[0][i - 1]) / (Points[1][i] - Points[1][i - 1]);
				double newX1 = Points[0][i - 1] + slope * (MaxY - Points[1][i - 1]);
				double newX2 = Points[0][i - 1] + slope * (MinY - Points[1][i - 1]);
				if (position == 2)
				{
					result[0][resultCount] = newX2;
					result[1][resultCount] = MinY;
					resultCount++;
					result[0][resultCount] = newX1;
					result[1][resultCount] = MaxY;
					resultCount++;
				} else
				{
					result[0][resultCount] = newX1;
					result[1][resultCount] = MaxY;
					resultCount++;
					result[0][resultCount] = newX2;
					result[1][resultCount] = MinY;
					resultCount++;
				}
			}
			lastPointPosition = position;
		}

		double finalP[][] = new double[2][resultCount];
		for (int i = 0; i < resultCount; i++)
		{
			finalP[0][i] = result[0][i];
			finalP[1][i] = result[1][i];
		}

		return finalP;
	}

	protected void plotSerie(ChartGraphics g, DataSerie s, int serieSec)
	{
		int seriesCount = series.size();
		s.hotAreas.removeAllElements();
		LineDataSerie l;
		if (s instanceof LineDataSerie)
			l = (LineDataSerie)s;
		else
			return;
		int count = l.getSize();
		int scX = 0;
		int scY = 0;
		int scYMin = 0;
		int scYMax = 0;
		int previousX = -1;
		int previousY = -1;
		boolean isNull = false;
		LineStyle currentBorder = border;
		int lineWidth = depth / seriesCount;
		int currentZ = (seriesCount - (serieSec + 1)) * lineWidth;
		if (interLineSpace < lineWidth)
			lineWidth -= interLineSpace;
		FillStyle normalStyle = new FillStyle(l.style.color);
		normalStyle = new FillStyle(l.style.color, l.style.alphaValue);
		FillStyle darkerStyle = new FillStyle(normalStyle.color.darker(), normalStyle.alphaValue);
		if (currentBorder == null)
			currentBorder = new LineStyle(0.2F, normalStyle.color.brighter(), 1);
		FillStyle darkerdarkerStyle = new FillStyle(normalStyle.color.darker().darker(), normalStyle.alphaValue);
		Scale tmpScaleY = super.getActiveYScale(s);
		Scale tmpScaleX = super.getActiveXScale(s);
		double linePoints[][] = new double[2][count];
		boolean nullPoints[] = new boolean[count];
		for (int iteration = 0; iteration < 3; iteration++)
		{
			if (l.fillStyle != null && count > 1 && iteration == 1)
			{
				double Points[][] = new double[2][count + 2];
				double XValue = 0.0D;
				for (int i = 0; i < count; i++)
				{
					XValue = ((Double)l.getElementX(i)).doubleValue();
					double YValue;
					if (l.getElementY(i) == null)
						YValue = 0.0D;
					else
						YValue = ((Double)l.getElementY(i)).doubleValue();
					if (i == 0)
					{
						Points[0][0] = XValue;
						Points[1][0] = tmpScaleY.min;
					}
					Points[0][i + 1] = XValue;
					Points[1][i + 1] = YValue;
				}

				Points[0][count + 1] = XValue;
				Points[1][count + 1] = tmpScaleY.min;
				if (fixedLimits)
					Points = clipLines(Points, tmpScaleY.max, tmpScaleY.min);
				int PointsSC[][] = new int[2][Points[0].length];
				for (int i = 0; i < Points[0].length; i++)
				{
					int tmpI = i;
					PointsSC[0][tmpI] = tmpScaleX.getScreenCoord(Points[0][i]) + currentZ;
					PointsSC[1][tmpI] = tmpScaleY.getScreenCoord(Points[1][i]) - currentZ;
				}

				darkerStyle.drawPolygon(g, PointsSC[0], PointsSC[1], PointsSC[0].length);
				int xs[] = new int[4];
				int ys[] = new int[4];
				xs[0] = PointsSC[0][PointsSC[0].length - 1];
				ys[0] = PointsSC[1][PointsSC[0].length - 1];
				xs[1] = PointsSC[0][PointsSC[0].length - 1] + lineWidth;
				ys[1] = PointsSC[1][PointsSC[0].length - 1] - lineWidth;
				xs[2] = PointsSC[0][PointsSC[0].length - 2] + lineWidth;
				ys[2] = PointsSC[1][PointsSC[0].length - 2] - lineWidth;
				xs[3] = PointsSC[0][PointsSC[0].length - 2];
				ys[3] = PointsSC[1][PointsSC[0].length - 2];
				darkerdarkerStyle.drawPolygon(g, xs, ys, 4);
			}
			for (int i = 0; i < count; i++)
			{
				double XValue = ((Double)l.getElementX(i)).doubleValue();
				isNull = false;
				double YValue = 0.0D;
				if (l.getElementY(i) == null)
					isNull = true;
				else
					YValue = ((Double)l.getElementY(i)).doubleValue();
				if (l.fillStyle != null)
					isNull = false;
				nullPoints[i] = isNull;
				scX = tmpScaleX.getScreenCoord(XValue);
				scY = tmpScaleY.getScreenCoord(YValue);
				if (l.style != null && (iteration == 0 || iteration == 1))
				{
					linePoints[0][i] = XValue;
					linePoints[1][i] = YValue;
				}
				if (l.drawPoint && iteration == 1 && !isNull && YValue <= tmpScaleY.max && YValue >= tmpScaleY.min)
				{
					g.setColor(l.pointColor);
					if (l.icon == null)
					{
						g.fillRect(scX - 3, scY - 3, 6, 6);
						Polygon p = new Polygon();
						p.addPoint(scX - 3, scY - 3);
						p.addPoint(scX - 3, scY + 3);
						p.addPoint(scX + 3, scY + 3);
						p.addPoint(scX + 3, scY - 3);
						l.hotAreas.addElement(p);
					} else
					{
						int iX = scX - l.icon.getWidth() / 2;
						int iY = scY - l.icon.getHeight() / 2;
						g.drawImage(l.icon, iX, iY);
						Polygon p = new Polygon();
						p.addPoint(iX, iY);
						p.addPoint(iX, iY + l.icon.getHeight());
						p.addPoint(iX + l.icon.getWidth(), iY + l.icon.getHeight());
						p.addPoint(iX + l.icon.getWidth(), iY);
						l.hotAreas.addElement(p);
					}
				}
				if (l.valueFont != null && iteration == 2 && !isNull && YValue <= tmpScaleY.max && YValue >= tmpScaleY.min)
				{
					g.setColor(l.valueColor);
					g.setFont(l.valueFont);
					String txt = l.doubleToString(new Double(YValue));
					String txtValue = txt;
					if (s.labelTemplate.length() > 0)
						txt = s.labelTemplate;
					if (l.dataLabels != null && l.dataLabels.length > i)
						txt = l.dataLabels[i];
					ChartLabel label = new ChartLabel(txt, txtValue, false, false);
					label.initialize(g, super.chart);
					label.paint(g, scX + 4 + currentZ + lineWidth, scY - 4 - currentZ - lineWidth - label.requiredHeight, -1, -1);
				}
				previousX = scX;
				previousY = scY;
			}

			if (iteration != 0 && iteration != 1 || l.style == null)
				continue;
			if (fixedLimits)
				linePoints = clipLines(linePoints, tmpScaleY.max, tmpScaleY.min);
			int linePointsSC[][] = new int[2][linePoints[0].length];
			for (int j = 0; j < linePoints[0].length; j++)
			{
				isNull = false;
				if (!fixedLimits && nullPoints[j])
					isNull = true;
				if (!isNull)
				{
					linePointsSC[0][j] = tmpScaleX.getScreenCoord(linePoints[0][j]);
					linePointsSC[1][j] = tmpScaleY.getScreenCoord(linePoints[1][j]);
				}
			}

			for (int j = 1; j < linePoints[0].length; j++)
			{
				isNull = false;
				if (!fixedLimits && (nullPoints[j] || nullPoints[j - 1]))
					isNull = true;
				if (isNull)
					continue;
				boolean draw = true;
				if (fixedLimits && linePoints[1][j - 1] == tmpScaleY.max && linePoints[1][j] == tmpScaleY.max)
					draw = false;
				if (fixedLimits && linePoints[1][j - 1] == tmpScaleY.min && linePoints[1][j] == tmpScaleY.min)
					draw = false;
				if (!draw)
					continue;
				int xs[] = new int[4];
				int ys[] = new int[4];
				xs[0] = linePointsSC[0][j - 1] + currentZ;
				ys[0] = linePointsSC[1][j - 1] - currentZ;
				xs[1] = linePointsSC[0][j] + currentZ;
				ys[1] = linePointsSC[1][j] - currentZ;
				xs[3] = linePointsSC[0][j - 1] + currentZ + lineWidth;
				ys[3] = linePointsSC[1][j - 1] - currentZ - lineWidth;
				xs[2] = linePointsSC[0][j] + currentZ + lineWidth;
				ys[2] = linePointsSC[1][j] - currentZ - lineWidth;
				FillStyle styleToUse = normalStyle;
				boolean backLineHidden = false;
				double slope = Math.abs((double)(ys[0] - ys[1]) / (double)(xs[1] - xs[0]));
				if (iteration == 0 && backLineHidden)
					currentBorder.draw(g, xs[2], ys[2], xs[3], ys[3]);
				if (ys[0] >= ys[1] && slope > 1.0D)
				{
					styleToUse = darkerStyle;
					backLineHidden = true;
				}
				if (iteration == 0)
					styleToUse.drawPolygon(g, xs, ys, 4);
				if (iteration == 0)
					currentBorder.draw(g, xs[2], ys[2], xs[3], ys[3]);
				if (iteration != 1)
					continue;
				currentBorder.draw(g, xs[0], ys[0], xs[1], ys[1]);
				if (!backLineHidden)
					currentBorder.draw(g, xs[3], ys[3], xs[0], ys[0]);
			}

		}

	}
}
